#region " LICENSE "
// DRILL - Dependency Resolution Interface Layer Library
// Copyright (c) 2008-2012 Wade A. Reynolds. All rights reserved.
// http://drill.codeplex.com/
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using Drill.Configuration;
using Drill.Extensibility;

namespace Drill.Core.Builders
{
	public class DrillBitBuilder : IDrillBitBuilder
	{
		private readonly IConfigurationHelper _configurationHelper;
		private readonly IConfigurationSourceSetFactory _configurationSourceSetFactory;
		private readonly string _drillBitName;
		private readonly string _drillBitAssemblyQualifiedTypeName;

		private IList<IConfigurationSource> _configurationSources;
		private IDrillBitInitContext _initContext;
		private IDrillBit _drillBit;

		public DrillBitBuilder(
			string drillBitName,
			string drillBitAssemblyQualifiedTypeName,
			IConfigurationSourceSetFactory configurationSourceSetFactory,
			IConfigurationHelper configurationHelper = null
			)
		{
			if (string.IsNullOrEmpty(drillBitName))
			{
				throw new ArgumentNullException("drillBitName");
			}
			if (string.IsNullOrEmpty(drillBitAssemblyQualifiedTypeName))
			{
				throw new ArgumentNullException("drillBitAssemblyQualifiedTypeName");
			}
			if (null == configurationSourceSetFactory)
			{
				throw new ArgumentNullException("configurationSourceSetFactory");
			}
			_drillBitName = drillBitName;
			_drillBitAssemblyQualifiedTypeName = drillBitAssemblyQualifiedTypeName;
			_configurationSourceSetFactory = configurationSourceSetFactory;
			_configurationHelper = configurationHelper;
		}

		public void BuildConfigurationSources()
		{
			_configurationSources = _configurationSourceSetFactory.CreateConfigurationSources();
		}

		public void BuildInitializationContext()
		{
			_initContext = 
				new DrillBitInitContext
					{
						ConfigurationHelper = _configurationHelper, 
						ConfigurationSources = _configurationSources,
						Name = _drillBitName
					};
		}

		public void CreateDrillBit()
		{
			var activator =
				new ObjectOrFactoryActivator<
						  IDrillBit
						, IDrillBitFactory
						, IDrillBitInitContext>();

			var activatorResult = activator.CreateInstance(_drillBitAssemblyQualifiedTypeName, _initContext);

			// activatorResult.Item1 = IDrillBit
			// activatorResult.Item2 = IDrillBitFactory
			_drillBit =
				(null != activatorResult.Item2)
					? activatorResult.Item2.CreateDrillBit()
					: activatorResult.Item1;
		}

		public IDrillBit GetDrillBit()
		{
			return _drillBit;
		}
	}
}